package org.example.new_hbps_backend_reconstruction.controller.patient;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.new_hbps_backend_reconstruction.common.results.R;
import org.example.new_hbps_backend_reconstruction.controller.patient.PatientDeviceController;
import org.example.new_hbps_backend_reconstruction.dto.PatientSessionDTO;
import org.example.new_hbps_backend_reconstruction.entity.request.PatientDeviceBindRequest;
import org.example.new_hbps_backend_reconstruction.entity.request.PatientDeviceCallbackRequest.PatientDeviceCallbackRequest;
import org.example.new_hbps_backend_reconstruction.entity.request.PatientDeviceUpdateRequest;
import org.example.new_hbps_backend_reconstruction.service.PatientDeviceV2Service;
import org.example.new_hbps_backend_reconstruction.utils.UserHolder;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/***
 * @author wangyifei
 * 心永手表对接, 替代原有接口
 * @see PatientDeviceController
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/patient/patientDeviceV2")
@Tag(description = "patientDeviceV2", name = "管理心永设备")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class PatientDeviceV2Controller {
    private final PatientDeviceV2Service patientDeviceV2Service;

    // /patient/patientDeviceV2/generateQRCodeString
    @Operation(
            summary = "生成二维码关联的字符串",
            description = "根据action和watch_id参数生成对应的二维码图片"
    )
    @Parameters({
            @Parameter(name = "action", description = "二维码动作类型", required = true),
            @Parameter(name = "watch_id", description = "关联的观察ID", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "二维码生成成功，返回二维码后面关联的信息"),
            @ApiResponse(responseCode = "500", description = "二维码生成失败")
    })
    @GetMapping("/generateQRCodeString")
    public R generateQRCode(@RequestParam String action, @RequestParam String watch_id) {
            log.info("生成二维码字符串action:{},watch_id:{}", action, watch_id);
            if("binding".equals( action)){
                // 构造二维码内容
                String content = "http://123.56.25.102:8848/patient/patientDeviceV2/bind_device_by_qrcode?"  + "watch_id=" + watch_id;
                Map<String, String> data = new HashMap<>();
                data.put("qrcode_string", content);
                // 返回二维码字符串
                return R.ok(data,"ok");
            }else if("calibration".equals( action)){
                // 构造二维码内容
                String content = "http://123.56.25.102:8848/patient/patientDeviceV2/calibration?"  + "watch_id=" + watch_id;
                Map<String, String> data = new HashMap<>();
                data.put("qrcode_string", content);
                // 返回二维码字符串
                return R.ok(data,"ok");
            }else{
                return R.ok(action,"action参数");
            }

    }
    @Operation(
            summary = "血压适配标定",
            description = "扫血压适配的二维码获得watch_id并执行后续流程,返回值为user_access_token"
    )
    @Parameters({
            @Parameter(name = "watch_id", description = "关联的观察ID", required = true)
    })
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "血压适配成功"),
            @ApiResponse(responseCode = "500", description = "血压适配失败")
    })
    @GetMapping("/calibration")
    public R calibration(@RequestParam String watch_id) {
        Long patientUid =patientDeviceV2Service.getPatientUidByDeviceUid(watch_id);
        if(patientUid==null){
            return R.failed("无效的watch_id");
        }
        Object obj = patientDeviceV2Service.generateUserAuthToken(patientUid);
        if(obj instanceof String token){
            Map<String, String> data = new HashMap<>();
            data.put("user_access_token", token);
            return R.ok(data,"ok");
        }
        return R.failed("未成功拿到user_access_token");
    }


    @Operation(summary = "绑定设备", description = "绑定设备")
    //@SysLog("绑定设备")
    @PostMapping("/bind_device")
    //@PreAuthorize("@pms.hasPermission('patient_patientDevice_add')")
    public R bindDevice(@RequestBody PatientDeviceBindRequest request) {
        return patientDeviceV2Service.bindPatientDevice(request.getImei(),
                request.getUid());
    }
    @Operation(summary = "微信扫码绑定设备", description = "扫码绑定设备")
    //@SysLog("绑定设备")
    @PostMapping("/bind_device_by_qrcode")
    //@PreAuthorize("@pms.hasPermission('patient_patientDevice_add')")
    public R bindDeviceByQrcode(@RequestParam String watch_id) {
        PatientSessionDTO user= UserHolder.getUser();
        if(user==null){
            return R.failed("user为空，请先登录，from /bind_device_by_qrcode接口");
        }
        log.info("用户ID:{}", user.getPatientUid());
        return patientDeviceV2Service.bindPatientDevice(watch_id,
                user.getPatientUid());
    }


    @Operation(summary = "更新设备", description = "更新设备")
    //@SysLog("更新设备")
    @PostMapping("/update_device")
    @PreAuthorize("@pms.hasPermission('patient_patientDevice_add')")
    public R updateDevice(@RequestBody PatientDeviceUpdateRequest request) {
        return patientDeviceV2Service.updatePatientDevice(request.getUid(),
                request.getHeight(),
                request.getWeight());
    }

    @Operation(summary = "解绑设备", description = "解绑设备")
    //@SysLog("解绑设备")
    @PostMapping("/unbind_device")
    @PreAuthorize("@pms.hasPermission('patient_patientDevice_add')")
    public R unbindDevice(@RequestBody PatientDeviceBindRequest request) {
        return patientDeviceV2Service.unbindPatientDevice(request.getUid());
    }

    @Operation(summary = "获取User Token", description = "获取User Token")
    //@SysLog("获取Token")
    @GetMapping("/refresh_token/{uid}")
    public R refreshToken(@PathVariable Long uid) {
        Object obj = patientDeviceV2Service.generateUserAuthToken(uid);
        if (obj instanceof String str) {
            return R.ok(str);
        }
        if (obj instanceof R r) {
            return r;
        }
        return R.failed(obj, "未知错误");
    }

    @Operation(summary = "通过id查询", description = "通过id查询")
    @GetMapping("/{uid}")
    @PreAuthorize("@pms.hasPermission('patient_patientDevice_view')")
    public R getById(@PathVariable Long uid) {
        return R.ok(patientDeviceV2Service.getByUid(uid));
    }

//    @Operation(summary = "获取企业access_token", description = "获取企业access_token")
//    @GetMapping("/get_company_access_token")
//    @PreAuthorize("@pms.hasPermission('patient_patientDevice_view')")
//    public R getCompanyAccessToken() {
//        return R.ok(patientDeviceV2Service.getAuthToken());
//    }

    @Operation(summary = "手表回调接口", description = "手表回调接口")
    @PostMapping("/callback")
    //TODO:后续完善@ Inner
    //@Inner(value = false)
    public R callback(@RequestBody PatientDeviceCallbackRequest request) {
        return patientDeviceV2Service.callback(request.getEventType(),
                request.getUserId(),
                request.getTimestamp(),
                request.getEventData());
    }

}

